www.gusucode.com > OpenGL 计算机图形学 Beizer Curve > OpenGL 计算机图形学 Beizer Curve/BEZIER曲线/Bezier.cpp

    // Bezier.cpp: implementation of the CBezier class.
//
//////////////////////////////////////////////////////////////////////

#include "Bezier.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CBezier::CBezier()
{
	m_nPoint=0;
	m_Point[0].x=520;m_Point[0].y=110;
	m_Point[1].x=130;m_Point[1].y=160;
	m_Point[2].x=700;m_Point[2].y=130;
	m_Point[3].x=623;m_Point[3].y=700;
	
	m_Point[4].x=20;m_Point[4].y=210;
	m_Point[5].x=130;m_Point[5].y=260;
	m_Point[6].x=400;m_Point[6].y=230;
	m_Point[7].x=223;m_Point[7].y=400;
	m_nPoint=7;
}
CBezier::~CBezier()
{

}
void CBezier::Draw(CDC *dc)
{
	int i,j,nPoint;
	double tt;
	double step;
	CPen dotpen(PS_DOT,1,RGB(0,0,200)),*oldpen;
	CPen pen(PS_SOLID,1,RGB(0,0,0));
	CPoint *point=m_Point;	
	CPoint p[BEZIER_STEP+1];

	step=(double)1.0/(double)BEZIER_STEP;
	nPoint=m_nPoint;

	oldpen=(CPen*)dc->SelectObject(&pen);
	while(nPoint>=4)
	{
		for(tt=0.0,j=0;tt<1.01;tt=tt+step,j++)
			p[j]=hor(3,point,tt);
		
		dc->SelectObject(&dotpen);
		dc->MoveTo(point[0].x,point[0].y);
		for(i=1;i<4;i++)
			dc->LineTo(point[i].x,point[i].y);
	
		dc->SelectObject(pen);
		dc->MoveTo(p[0].x,p[0].y);
		for(i=1;i<j;i++)
			dc->LineTo(p[i].x,p[i].y);
		nPoint-=3;
		point+=3;
	}
	dc->SelectObject(oldpen);
}

CPoint CBezier::hor(int degree, CPoint *point, double t)
{
	int i,choose_i;
	double fact,t1,x,y;
	CPoint aux;
	t1=1.0-t;
	fact=1.0;
	choose_i=1;
	x=(double)point[0].x*t1;
	y=(double)point[0].y*t1;
	for(i=1;i<degree;i++)
	{
		fact=fact*t;
		choose_i=choose_i*(degree-i+1)/i;
		x=(x+fact*choose_i*point[i].x)*t1;
		y=(y+fact*choose_i*point[i].y)*t1;
	}
	x=x+fact*t*(double)point[degree].x;
	y=y+fact*t*(double)point[degree].y;
	aux.x=(long)x;
	aux.y=(long)y;
	return aux;
}

BOOL CBezier::PtInBezier(CPoint point)
{
	int i,j,nPoint;
	double tt;
	double step;
	CRect rec;
	int RecWidth=5;

	CPoint *pnt=m_Point;	
	CPoint p[BEZIER_STEP+1];

	step=(double)1.0/(double)BEZIER_STEP;
	nPoint=m_nPoint;

	while(nPoint>=4)
	{
		for(tt=0.0,j=0;tt<1.01;tt=tt+step,j++)
			p[j]=hor(3,pnt,tt);
		for(i=1;i<j;i++)
		{
			rec.left=p[i-1].x;
			rec.top=p[i-1].y;
			rec.right=p[i].x;
			rec.bottom=p[i].y;		
			rec.NormalizeRect();
			rec.InflateRect(1,1,1,1);
			if(PtInRect(&rec,point)) return TRUE;
		}
		nPoint-=3;
		pnt+=3;
	}
	return FALSE;
}

void CBezier::Move(UINT offx, UINT offy)
{
	UINT i;
	for(i=0;i<m_nPoint;i++)
	{
		m_Point[i].x+=offx;
		m_Point[i].y+=offy;
	}
}